home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’93 / Wavy / WavyColumns.c < prev   
Encoding:
C/C++ Source or Header  |  1993-06-18  |  5.2 KB  |  221 lines  |  [TEXT/KAHL]

  1. /*
  2.     Test mappings
  3. */
  4.  
  5. #include "Instructions.h"
  6. #include "Wavy.h"
  7.  
  8. #include <QDOffscreen.h>
  9. #include <FixMath.h>
  10.  
  11. static void
  12. MakeWavyTable(short amplitude, short wavyTable[32])
  13. {
  14. #define    cycleSize (frameCount / 2)
  15. #define twoPiOverCycleSize (205887/cycleSize)
  16.  
  17.     short    i;
  18.     
  19.     for (i = 0; i < 32; i++)
  20.         *wavyTable++ = (amplitude * Frac2Fix(FracSin(i * twoPiOverCycleSize))+32768) >> 16;
  21. }
  22.  
  23. static void
  24. MapCoordinates(short width, short height, short x, short y,
  25.                 short *resultX, short *resultY,
  26.                 short frameNumber,
  27.                 short wavyTable[32])
  28. {
  29.     *resultX = x;
  30.     *resultY = y + wavyTable[(x + frameNumber) % 32];
  31.  
  32.     while (*resultX < 0)
  33.         *resultX += width;
  34.     while (*resultY < 0)
  35.         *resultY += height;
  36.  
  37.     *resultX %= width;
  38.     *resultY %= height;
  39. }
  40.  
  41. /*
  42.     Generate the addresses for one 32-pixel column. 
  43. */
  44.  
  45. static void
  46. GenerateMappingColumn(long *buffer1, short width, short height, short rowBytes,
  47.                          short frameNumber, short wavyTable[32])
  48. {
  49.     long    *offsetHere;
  50.     short    x, y;
  51.     
  52.     offsetHere = buffer1;
  53.  
  54.     for (y = 0; y < height; ++y) {
  55.         for (x = 0; x < 32; ++x)
  56.             {
  57.             short    destinationX, destinationY;
  58.  
  59.             destinationX = x;
  60.             destinationY = y + wavyTable[(x + frameNumber) % 32];
  61.         
  62.             while (destinationX < 0)
  63.                 destinationX += width;
  64.             while (destinationY < 0)
  65.                 destinationY += height;
  66.         
  67.             destinationX %= width;
  68.             destinationY %= height;
  69.  
  70.             *offsetHere++ = (long)destinationY * rowBytes + destinationX;
  71.             }
  72.     }
  73. }
  74.  
  75. //
  76. // Blit the entire bitmap from source to dest using a technique similar to what
  77. // we'd like to compile.
  78. //
  79. //    Use 5 destination registers so we can use 16-bit constant offsets in instructions
  80. //
  81. long
  82. WriteSomeCode(short height, short rowBytes, long *mappingTable, short *placeForCode)
  83. {
  84.     short    i, x, y;
  85.     
  86.     long    destRegisters[5];
  87.     long    targetByte;
  88.     short    *theCode = placeForCode;
  89.     
  90.     for (i = 0; i < 5; i++)
  91.         destRegisters[i] = 32768 + i * 65536L;
  92.  
  93.     for (y = 0; y < height; ++y)
  94.         {
  95.         for (x = 0; x < 32; ++x) {
  96.             long    registerOffset;
  97.             
  98.             targetByte = *mappingTable++;
  99.         
  100.             for (i = 0; i < 5; i++) {
  101.                 registerOffset = targetByte - destRegisters[i];
  102.                 if (registerOffset >= -32768 && registerOffset < 32768) {
  103.                     switch(i) {
  104.                         case 0:
  105.                             *(*(short **) &theCode)++ = move_b_off_a5_to_a0;
  106.                             *(*(short **) &theCode)++ = x;
  107.                             *(*(short **) &theCode)++ = registerOffset;
  108.                             break;
  109.                         case 1:
  110.                             *(*(short **) &theCode)++ = move_b_off_a5_to_a1;
  111.                             *(*(short **) &theCode)++ = x;
  112.                             *(*(short **) &theCode)++ = registerOffset;
  113.                             break;
  114.                         case 2:
  115.                             *(*(short **) &theCode)++ = move_b_off_a5_to_a2;
  116.                             *(*(short **) &theCode)++ = x;
  117.                             *(*(short **) &theCode)++ = registerOffset;
  118.                             break;
  119.                         case 3:
  120.                             *(*(short **) &theCode)++ = move_b_off_a5_to_a3;
  121.                             *(*(short **) &theCode)++ = x;
  122.                             *(*(short **) &theCode)++ = registerOffset;
  123.                             break;
  124.                         case 4:
  125.                             *(*(short **) &theCode)++ = move_b_off_a5_to_a4;
  126.                             *(*(short **) &theCode)++ = x;                            
  127.                             *(*(short **) &theCode)++ = registerOffset;
  128.                             break;
  129.                         default:
  130.                             Debugger();
  131.                             ExitToShell();
  132.                             break;
  133.                     }                
  134.                     goto gotRegister;
  135.                 }
  136.             }
  137.             // So, we have no register coverage for the destination
  138.             // We’ll have to emit some slower code.
  139.             registerOffset = targetByte - 32768;
  140.             *(*(short **) &theCode)++ = immediate_long_load_d0;
  141.             *(*(long **) &theCode)++ = registerOffset;
  142.             *(*(short **) &theCode)++ = move_byte_da5_a0_d0_L;
  143.             *(*(short **) &theCode)++ = x;
  144.             *(*(short **) &theCode)++ = no_constant_for_load;
  145. gotRegister:
  146.             ;
  147.         }
  148.         // add rowbytes to the row register
  149.         *(*(short **) &theCode)++ = adda_w_const_a5;
  150.         *(*(short **) &theCode)++ = rowBytes;
  151.     }
  152.     *(*(short **) &theCode)++ = rts;
  153.     return (char *)theCode - (char *)placeForCode;
  154. }
  155.  
  156. /* array with code */
  157.  
  158. Boolean
  159. InitColumns(short amplitude, short width, short height, short rowBytes, short *frameCode[frameCount], Handle dialogItem)
  160. {
  161.     long    *columnMap;
  162.     short    frame;
  163.     short    wavyTable[32];
  164.  
  165.     MakeWavyTable(amplitude, wavyTable);
  166.  
  167.     columnMap = (long *)NewPtr(sizeof(long) * 32 * (long)height);
  168.     if (columnMap == nil)
  169.         return false;
  170.  
  171.     for (frame = 0; frame < frameCount; frame++)
  172.     {
  173.         Str255    frameNumberString;
  174.         long    size;
  175.  
  176.         /* update dialog status */
  177.         NumToString(frame+1, frameNumberString);
  178.         SetIText(dialogItem, frameNumberString);
  179.  
  180.         frameCode[frame] = (short *) NewPtr(12 * 32 * (long)height        // move the rows
  181.                                             + 6 * 20 * (long)height        // the row reloads
  182.                                             + 500);                        // el sloppolo
  183.         if (frameCode[frame] == nil)
  184.             return false;
  185.  
  186.         GenerateMappingColumn(columnMap, width, height, rowBytes, frame, wavyTable);
  187.         size = WriteSomeCode(height, rowBytes, columnMap, frameCode[frame]);
  188.         SetPtrSize((Ptr)frameCode[frame], size);
  189.     }
  190.  
  191.     DisposePtr((Ptr)columnMap);
  192.  
  193.     FlushCache();
  194.     return true;
  195. }
  196.  
  197. void DrawColumn(char *sourceBase, char *destinationBase, short frameNumber, short *frameCode[frameCount])
  198. {
  199.     short    *code = frameCode[frameNumber];
  200.  
  201.     asm {
  202.         movem.l    a0-a6, -(sp)
  203.  
  204.         movea.l    destinationBase, a0
  205.         adda.l    #0x8000, a0
  206.         movea.l    a0, a1
  207.         adda.l    #0x10000, a1
  208.         movea.l    a1, a2
  209.         adda.l    #0x10000, a2
  210.         movea.l    a2, a3
  211.         adda.l    #0x10000, a3
  212.         movea.l    a3, a4
  213.         adda.l    #0x10000, a4
  214.         movea.l    sourceBase, a5
  215.  
  216.         movea.l    code, a6
  217.         jsr        (a6)
  218.         movem.l    (sp)+, a0-a6
  219.     }
  220. }
  221.